<template>
  <div class="min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 py-8">
    <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="text-center mb-6">
        <h1 class="text-3xl font-bold">黄金矿工</h1>
        <p class="text-sm text-gray-600">按空格发射钩子，抓住矿物得分。简化版实现。</p>
      </div>

      <div class="bg-white rounded-lg shadow p-4">
        <div class="flex items-center justify-between mb-3">
          <div>分数: <span class="font-medium">{{ score }}</span></div>
          <div>
            <button class="px-3 py-1 bg-blue-600 text-white rounded" @click="start">开始</button>
            <button class="px-3 py-1 bg-gray-200 rounded" @click="reset">重置</button>
          </div>
        </div>

        <div>
          <canvas ref="canvas" class="w-full border rounded" style="height:420px"></canvas>
        </div>
        <div class="text-xs text-gray-500 mt-2">提示：按空格发射钩子。钩子会自动收回。</div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
// import asset images via bundler so paths resolve correctly (avoid router treating them as routes)
import hookSrc from '~/assets/images/hook.svg'
import stoneSrc from '~/assets/images/stone.svg'
import gemSrc from '~/assets/images/gem.svg'
import goldSrc from '~/assets/images/gold.svg'

const canvas = ref(null)
let ctx
let raf = 0
let running = false
let angle = 0
let swinging = true
let extending = false
let retracting = false
let hookX = 0
let hookY = 0
let hookLen = 0
let hookMax = 0 // will be computed based on canvas size
let attached = null

const score = ref(0)
const items = []

// sprite images
const hookImg = new Image()
const itemImgs = { 1: new Image(), 2: new Image(), 3: new Image() }

function reset(){
  score.value = 0
  items.length = 0
  initItems()
  running = false
  swinging = true
  extending = false
  retracting = false
  attached = null
}

function start(){ if(!running){ running=true; loop() } }

function initItems(){
  const c = canvas.value
  if(!c) return
  const cols = 7
  for(let i=0;i<10;i++){
    items.push({ x: 80 + Math.random()*(c.width-160), y: 100 + Math.random()*220, r: 12 + Math.random()*14, v: Math.floor(Math.random()*3)+1 })
  }
}

function loop(){
  const c = canvas.value
  if(!c) return
  ctx = c.getContext('2d')
  update()
  draw()
  if (running) raf = requestAnimationFrame(loop)
}

function update(){
  const c = canvas.value
  if (!c) return
  // swing
  if (swinging && !extending && !retracting) {
    angle += 0.03
    hookLen = 60
  }
  if (extending) {
    // extend faster; allow to reach farther targets
    hookLen += 10
    if (hookLen > hookMax) { extending = false; retracting = true }
  }
  if (retracting) {
    // retract speed depends on whether an item is attached
    hookLen -= attached ? Math.max(6, 14 - attached.v*2) : 14
    if (hookLen <= 60) { retracting = false; swinging = true; hookLen = 60; if (attached) { // collect
      score.value += attached.v*10; // remove
      const idx = items.indexOf(attached)
      if (idx>=0) items.splice(idx,1)
      attached = null
    }}
  }
  // update hook pos
  const cx = c.width/2
  const cy = 60
  hookX = cx + Math.cos(angle)*hookLen
  hookY = cy + Math.sin(angle)*hookLen
  if (extending && !attached) {
    for(const it of items){
      const dx = it.x - hookX
      const dy = it.y - hookY
      if (Math.hypot(dx,dy) < it.r + 8) { attached = it; extending=false; retracting=true; break }
    }
  }
  if (attached) {
    // attached follows hook end
    attached.x = hookX
    attached.y = hookY
  }
}

function draw(){
  const c = canvas.value
  const w = c.width, h = c.height
  ctx.clearRect(0,0,w,h)
  // background
  ctx.fillStyle = '#f1f5f9'
  ctx.fillRect(0,0,w,h)
  // crane origin
  ctx.fillStyle = '#444'
  const cx = w/2, cy = 60
  ctx.beginPath(); ctx.arc(cx,cy,6,0,Math.PI*2); ctx.fill()
  // rope
  ctx.strokeStyle = '#555'
  ctx.lineWidth = 2
  ctx.beginPath(); ctx.moveTo(cx,cy); ctx.lineTo(hookX,hookY); ctx.stroke()
  // hook (use sprite if available)
  if (hookImg.complete && hookImg.naturalWidth) {
    ctx.save()
    ctx.translate(hookX, hookY)
    const ang = Math.atan2(hookY - cy, hookX - cx)
    ctx.rotate(ang)
    ctx.drawImage(hookImg, -14, -14, 28, 28)
    ctx.restore()
  } else {
    ctx.fillStyle = '#333'
    ctx.fillRect(hookX-6,hookY-6,12,12)
  }
  // items (use sprites when loaded)
  for(const it of items){
    const img = itemImgs[it.v]
    if (img && img.complete && img.naturalWidth) {
      ctx.drawImage(img, it.x - it.r, it.y - it.r, it.r*2, it.r*2)
    } else {
      ctx.beginPath(); ctx.fillStyle = it.v===3? '#f59e0b' : (it.v===2? '#a3e635' : '#cbd5e1')
      ctx.arc(it.x,it.y,it.r,0,Math.PI*2); ctx.fill()
    }
  }
}

function onKey(e){
  // Support different browsers: e.code === 'Space' is standard; some browsers report e.key as ' ' or 'Spacebar'
  if (e.code === 'Space' || e.key === ' ' || e.key === 'Spacebar'){
    // prevent the page from scrolling when pressing space in the game
    // allow default if an input/textarea has focus to avoid breaking form behavior
    const active = document.activeElement
    const isTyping = active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' || active.isContentEditable)
    if (!isTyping) {
      e.preventDefault()
      if (!running) start()
      if (swinging && !extending && !retracting) { extending = true; swinging = false }
    }
  }
}

onMounted(()=>{
  const c = canvas.value
  c.width = 800
  c.height = 420
  // compute hook max as nearly the canvas diagonal so it can reach corners
  hookMax = Math.hypot(c.width, c.height) * 0.9
  // load sprites using imported asset paths so Vite/Nuxt resolves them
  hookImg.src = hookSrc
  itemImgs[1].src = stoneSrc
  itemImgs[2].src = gemSrc
  itemImgs[3].src = goldSrc
  initItems()
  window.addEventListener('keydown', onKey)
})
onBeforeUnmount(()=>{
  window.removeEventListener('keydown', onKey)
  cancelAnimationFrame(raf)
})
</script>

<style scoped>
</style>
